`include "fxu_mul.vh"

`define print(v) $display(`"variable v = %h`", v)

module tb_top;
   
   // input signal
   logic [`JZ4785_UMUL-1:0] i_ucode;
   logic [15:0] 			i_a;
   logic [15:0] 			i_b;
   logic [15:0] 			i_wd;

   

   logic [32:0] final_pp0, final_pp1;
   
   Mmultiply_mix U_mm(
					  .o_final_pp0(final_pp0),
					  .o_final_pp1(final_pp1),
					  .i_a(i_a),
					  .i_b(i_b),
					  .i_sign(i_ucode[0]), // sign or not
					  .i_mode8(i_ucode[7:4]==`JZ4785_MUL_DF_B & ~i_ucode[1]), // should change the dotp control signal 
					  .i_dotp(i_ucode[1])
					  );

   logic [15:0] result;   
   Maddsub_mix U_addsub_mix(
							.o_result(result),
							.i_ucode(i_ucode),
							.i_mul_pp0(final_pp0),
							.i_mul_pp1(final_pp1),
							.i_wd(i_wd) );
   

   task gen_rand_vector;
	  inout [15:0] a, b, c;
	  {a, b} = $random;
	  c = $random;
   endtask // gen_random
   

   bit 			   unsigned [32:0] i;
   shortint 	   i16L, i16H, i16;
   shortint 	   unsigned u16;
   
   
   int 			   i32;
   
   initial begin
	  #1;

	  // test madd of 8b
	  // i_ucode = `JZ4785_UMUL_MADDV_B;
	  // for(i=0;i<65536;i++)
	  // 	begin
	  // 	   gen_rand_vector(i_a, i_b, i_wd);
	  // 	   i16L = $signed(i_a[7:0]) * $signed(i_b[7:0]) + $signed(i_wd[7:0]);
	  // 	   i16H = $signed(i_a[15:8]) * $signed(i_b[15:8]) + $signed(i_wd[15:8]);
	  // 	   u16 = {i16H[7:0], i16L[7:0]};
	  // 	   #1;
	  // 	   $display("%x*%x+%x = %x+%x, correct : %04x, result : %04x  => %s",
	  // 				i_a[7:0], i_b[7:0], i_wd[7:0], $signed(i_a[7:0])*$signed(i_b[7:0]), i_wd[7:0],
	  // 				// i_a[15:8], i_b[15:8], i_wd[15:8],
	  // 				u16, result,
	  // 				u16===result ? "equal" : "Not Equal"
	  // 				);
	  // 	   if(u16!==result)
	  // 		 begin
	  // 			$finish;
	  // 		 end
	  // 	   // $display("U_addsub_mix.result = %x", U_addsub_mix.result);
		   
	  // 	   // $display("U_addsub_mix.final_pp0 = %x", U_addsub_mix.final_pp0 + U_addsub_mix.final_pp1);
	  // 	   // $display("U_addsub_mix.final_pp1 = %x", U_addsub_mix.final_pp1);
		   
	  // 	end // for (i=0;i<65536;i++)


	  // `JZ4785_UMUL_MADDV_H

	  i_ucode = `JZ4785_UMUL_DOTP_S_H;
	  for(i=0;i<10;i++)
		begin
		   gen_rand_vector(i_a, i_b, i_wd);
		   i16L = $signed(i_a[7:0]) * $signed(i_b[7:0]) + $signed(i_wd[7:0]);
		   i16H = $signed(i_a[15:8]) * $signed(i_b[15:8]) + $signed(i_wd[15:8]);
		   i16 = i16L + i16H;
		   #1;
		   $display("correct : %04x, result : %04x  => %s",
					i16, result, i16===result ? "equal" : "Not Equal");
		   $display("U_addsub_mix.i_mul_pp0 = %x", U_addsub_mix.i_mul_pp0);
		   $display("U_addsub_mix.i_mul_pp1 = %x", U_addsub_mix.i_mul_pp1);

		   // $display("U_addsub_mix.final_pp0 = %x", U_addsub_mix.final_pp0);
		   
		   `print(U_addsub_mix.cmpr_src[0]);
		   `print(U_addsub_mix.cmpr_src[1]);
		   `print(U_addsub_mix.cmpr_src[2]);
		   // `print(U_addsub_mix.cmpr_src[0]);
		   
		   
		end

   end
   
endmodule // Mtop

   
